package com.automapper.utils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.OneToMany;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import com.automapper.exception.AutoMapperException;

public class ObjectFacade {

	private List<FieldFacade> goalFieldFacades = null;
	private List<String> columnNames = null;
	private Object obj;

	public ObjectFacade(Object obj) {
		this.obj = obj;
	}
	
	public List<FieldFacade> getFieldFacades() {
		if (goalFieldFacades == null) {
			goalFieldFacades = new ArrayList<>();
			
			Field[] fields = obj.getClass().getDeclaredFields();
			for (Field field : fields) {
				if (field.getAnnotation(Column.class) != null || field.getAnnotation(OneToMany.class) != null) {
					field.setAccessible(true);
					goalFieldFacades.add(new FieldFacade(field, obj));
				}
			}
		}
		return goalFieldFacades;
	}
	
	public FieldFacade getFiledFacade(String columnName) {
		FieldFacade fieldFacade = null;
		List<FieldFacade> list = this.getFieldFacades();
		for (FieldFacade f : list) {
			if (columnName.equalsIgnoreCase(f.getColumnName())) {
				fieldFacade = f;
				break;
			} 
		}
		AutoMapperException.NullRuntimeException(fieldFacade, "ObjectFacade.getFiledFacade方法：找不到column_name:%s的field; 对象：%s", columnName, this.obj);
		return fieldFacade;
	}
	
	public List<String> getColumnNames() {
		if (CollectionUtils.isNotEmpty(columnNames)) {
			return columnNames;
		}
		
		columnNames = new ArrayList<>();		
		List<FieldFacade> list = this.getFieldFacades();
		for (FieldFacade fieldFacade : list) {
			Column column = fieldFacade.getField().getAnnotation(Column.class);
			if (column != null && StringUtils.isNoneBlank(column.name())) {
				columnNames.add(column.name());
			} else if (column != null) {
				columnNames.add(fieldFacade.getFieldName());
			}
		}
		AutoMapperException.CollectionIsBlankRuntimeException(columnNames, "你确定你不是在逗我吗，对象%s字段全是空的", obj);
		return columnNames;
	}
	
	/**
	 * 获取主键Field对象
	 * @param object
	 * @return Field
	 */
	public FieldFacade getPrimaryKeyField() {
		FieldFacade fieldFacade = null;
		List<FieldFacade> filedFacades = this.getFieldFacades();
		for (FieldFacade ff : filedFacades) {
			Id id = ff.getField().getAnnotation(Id.class);
			if (id != null) {
				fieldFacade = ff;
				break;
			}
		}
		AutoMapperException.NullRuntimeException(fieldFacade, "对象%s没有定义主键", this.obj);
		return fieldFacade;
	}
	
	public String getPrimaryKeyColumnName() {
		FieldFacade fieldFacade = this.getPrimaryKeyField();
		return fieldFacade.getColumnName();
	}
	
	public FieldFacade getJoinColumnField() {
		FieldFacade fieldFacade = null;
		List<FieldFacade> facades = this.getFieldFacades();
		for (FieldFacade facade : facades) {
			if (facade.isJoinColumn()) {
				fieldFacade = facade;
				break;
			}
		}
		AutoMapperException.NullRuntimeException(fieldFacade, "对象没有@JoinColumn注解");
		return fieldFacade;
	}

	public Object getOriginalObject() {
		return obj;
	}
}
